import functools

import requests
from pex import toml

from constants.consts import USER_AGENT_GITEE, USER_AGENT_GITCODE
from logger import logger

TYPE_FILE = "files"
TYPE_REVIEW = "review"
TYPE_COMMENTS = "comments"

LOGGER = logger.CustomLogger()


def skip_if_debug(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        if hasattr(self, 'debug_mode') and self.debug_mode:
            LOGGER.debug(f"func {func} not executed, args: {args}")
            return requests.Response()
        return func(self, *args, **kwargs)

    return wrapper


class GitClient:
    def __init__(self, debug_mode=False, owner="", name="", user_agent=USER_AGENT_GITEE):
        self.debug_mode = debug_mode
        cfg = toml.load('config/' + user_agent.replace("-", "_") + '/config.toml')
        url_prefix = cfg.get("repo", {}).get("url_prefix")
        self.url_prefix = f"{url_prefix}/{owner}/{name}/pulls"
        self.user_agent = user_agent

    def get_url(self, pr_number, type=None):
        if type:
            return f"{self.url_prefix}/{pr_number}/{type}"
        return f"{self.url_prefix}/{pr_number}"

    def get_files(self, pr_number, params):
        url = self.get_url(pr_number, TYPE_FILE)
        response = requests.get(url, params=params)
        if response.status_code == 200:
            return response.json()
        else:
            LOGGER.error(f"[{pr_number}] get {url} failed, code {response.status_code}, reason {response.reason}")
        return []

    def get_filenames(self, pr_number, params):
        url = self.get_url(pr_number, TYPE_FILE)
        response = requests.get(url, params=params)
        files = []
        if response.status_code == 200:
            res = response.json()
            for f in res:
                files.append(f['filename'])
        else:
            raise Exception(f"code {response.status_code}, reason {response.reason}")
        return files

    def get_pr_info(self, pr_number, token):
        url = self.get_url(pr_number)
        response = None
        if self.user_agent == USER_AGENT_GITEE:
            params = {
                'Authorization': f'token {token}'
            }
            response = requests.get(url, params=params)
        if self.user_agent == USER_AGENT_GITCODE:
            headers = {
                'private-token': token,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
            response = requests.get(url, headers=headers)
        if response and response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"response {response}")

    def get_comments(self, pr_number, token):
        url = self.get_url(pr_number, TYPE_COMMENTS)
        response = None
        if self.user_agent == USER_AGENT_GITEE:
            params = {
                'Authorization': f'token {token}',
                "comment_type": "diff_comment",
                "per_page": 100
            }
            response = requests.get(url, params=params)
        if self.user_agent == USER_AGENT_GITCODE:
            headers = {
                'private-token': token,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
            params = {
                "comment_type": "diff_comment",
                "per_page": 100
            }
            response = requests.get(url, headers=headers, params=params)
        if response and response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"response {response}")

    @skip_if_debug
    def review(self, pr_number, token):
        headers = {}
        if self.user_agent == USER_AGENT_GITEE:
            headers = {'Authorization': f'token {token}'}
        if self.user_agent == USER_AGENT_GITCODE:
            headers = {
                'private-token': token,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
        url = self.get_url(pr_number, TYPE_REVIEW)
        return requests.post(url, headers=headers)

    @skip_if_debug
    def comment(self, pr_number, token, json):
        headers = {}
        if self.user_agent == USER_AGENT_GITEE:
            headers = {'Authorization': f'token {token}'}
        if self.user_agent == USER_AGENT_GITCODE:
            headers = {
                'private-token': token,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
        url = self.get_url(pr_number, TYPE_COMMENTS)
        return requests.post(url, headers=headers, json=json)
